section .data
    versions db "New-C Lang Versions 0.0.1 ", 10
    v_string db "%f, %d", 10
section .bss    ;未初始化的全局变量和静态变量
section .rdata  ;只读区
section .text   ;代码区
    global main
    extern out
    extern __stack_chk_fail@PLT
main:
    push	rbp
    mov rbp, rsp
    sub rsp, 16 ;函数栈 向下生长
    ;leave:   
    ; mov rsp, rbp
    ; pop rbp

    ; nasm -f elf64 -o tag.o tag.asm
    ; gcc tag.o sys_func.o

    ; gcc-x64-linux 调用传参约定
    ; 非浮点数: rdi，rsi，rdx，rcx，r8，r9 6个参数以后"从右往左"依次入栈
    ; 浮点数: xmm0 ~ xmm7 8个参数后"从右往左"依次入栈
    ; 所有入栈参数的字宽以8字节对齐, 栈以16字节对齐 取入栈参数时默认减16锁定参数栈的栈底(call的rip+函数内部的pushq rbp 共计16字节)
    ; 如果参数有浮点数和非浮点数, 也按照上面规律先存寄存器再入栈
    ; 例如 float a, int b 对应 xmm0, xdi
    
    ; 取内存地址, lea宽度要根据机器最大位数来使用寄存器; 
    ; movd 单精度(4字节) float     计算: addss xmmreg, mem32/xmmreg    结果在 xmmreg
    ; movq 双精度(8字节) double    计算: addsd xmmreg, mem64/xmmreg    结果在 xmmreg
    ; [rel FLT0] 意思是 [rip+FLT0] 不这样写gcc会报错, nasm又不能直接写rip寄存器;  也不知道为什么QAQ! cvtsd2ss
    ;cvtss2sd xmm0, [rel FLT0]
    ;movq xmm1, [rel FLT1]

    ;cvtss2si esi, [rel FLT0]
    ;cvtsd2si rdx, xmm1

    mov dl, 2
    movsx edx, dl
    mov eax, 1
    mov ebx, edx
    cdq
    mov rdx, 0
    idiv ebx
    
    idiv  ebx ;以imul指令第一个位数决定值的存放
    call	__stack_chk_fail@PLT
    leave
	ret

section .data    
    FLT0:
        dd    1123434234
    FLT1:
        DD    996432413
        DD    1079953375
    FLT2 db "wo shi yuan rui %f, %d, %n4 \n"

;movsx 符号位扩展
;movzx 零位扩展
; 浮点数入栈
;leaq	-8(%rsp), %rsp 
; 把rsp的值-8的内存地址赋值给rsp 有点绕;其实也不难理解 rsp-8的内存地址 就是 rsp-8
; 因为: rsp本身存的就是rsp的内存地址, leaq rsp内存地址 = rsp寄存器的值
;       所以leaq rsp-8的内存地址 = sub 8, %rsp
;       直接写 subq $8, %rsp也是可以的, 至于gcc为什么这样写就不知道了

